
<!--
 * @Author: Jackie
 * @Date: 2020-12-05 21:10:06
 * @LastEditors: Please set LastEditors
 * @LastEditTime: 2020-12-11 16:44:24
 * @Description: 日历组件
 * @FilePath: \vue_demo\vue_mina\src\components\Calendar.vue
-->
<template>
  <div class='demo-app'>
    <!--begin:日历部分-->
    <div class='demo-app-main'>
      <el-collapse  accordion >
          <span class="tips">Lorem ipsum dolor, sit amet consectetur adipisicing elit. Quas fugiat magnam repellendus nihil minima. Omnis nihil consectetur sapiente modi doloremque. A consequatur inventore molestias et veritatis error tempore, laudantium magnam.</span>
          <p class="totalSchedule">日 程 <span>{{ eventList.length }}</span></p>
        <el-collapse-item v-for="item in eventList" :key="item.id"  :name="item.id">
          <template slot="title">
            <i :class="item.allDay==true?'el-icon-sunny':'el-icon-sunrise'"></i> 
             {{' '+item.dayStr+' '+item.title}}
          </template>
          <div class="start_end">
            <div>起始日期: {{item.startStr}}</div>
            <div>结束日期: {{item.endStr}}</div>
          </div>
          <div class="list_Title" >{{item.title}}；</div>
          <el-popover
            placement="top-start"
            width="200"
            trigger="hover"
            >
            <slot>{{item.areaText}}</slot>
            <div slot="reference">{{item.areaText|ellipsis}}</div>
          </el-popover>
          <el-button @click="deleteCalendar(item.id)" class="deleteCalendar" ><i class="el-icon-delete"></i></el-button>
        </el-collapse-item>
      </el-collapse>
      
      <FullCalendar ref="fullCalendar"
        class='demo-app-calendar'
        :options='calendarOptions'
      >
        <template v-slot:eventContent='arg'>
          <b>{{ arg.timeText }}</b>
          <i>{{ arg.event.title }}</i>
        </template>
      </FullCalendar>
      
    </div>
   <!--end:日历部分-->


    <!--begin:对话框--新建/修改日程-->
      <el-dialog  :title="dialog_title" :visible.sync="dialogFormVisible">
        <el-form :model="form" label-width="40px">
          <!--主题内容-->
          <el-form-item label="主题">
            <el-input v-model="form.title" placeholder="主题" class="title" ></el-input>
          </el-form-item>
          <el-form-item label="全天" >
              <el-switch
              v-model="isAllday"
              active-color="#1867c0"
              inactive-color="#C0C0C0"
              >
            </el-switch>
          </el-form-item> 
          <el-form-item label="开始" >
              <el-date-picker type="date" placeholder="选择日期" v-model="form.start" style="width:50%;"></el-date-picker>
              -
              <el-time-picker placeholder="选择时间" v-model="form.start" style="width:45%;" :disabled="isAllday"></el-time-picker>
          </el-form-item> 
          <el-form-item label="结束" >
              <el-date-picker type="date" placeholder="选择日期" v-model="form.end" style="width:50%;"></el-date-picker>
              -
              <el-time-picker placeholder="选择时间" v-model="form.end" style="width:45%;" :disabled="isAllday"></el-time-picker>
          </el-form-item>
          <el-form-item label="分类" >
            <el-color-picker v-model="form.color" show-alpha :predefine="predefineColors" size="medium"></el-color-picker>
          </el-form-item> 
          <el-form-item  label="内容">
            <el-input type="textarea" :rows="2" placeholder="内容" v-model="form.areaText"  ></el-input>
          </el-form-item>         
        </el-form>

        <!--取消/确定-->
        <div slot="footer" class="dialog-footer">
          <el-button type="primary" v-on:click="dialogFormVisible = false; addCalendar(selectInfo)"  v-show="isDialogVisible">确 定</el-button>
          <el-button type="primary" v-on:click="dialogFormVisible = false;updateCalendar(clickInfo)" v-show="!isDialogVisible">修 改</el-button>
          <el-button @click="dialogFormVisible = false;resetForm()" >取 消</el-button>
          <el-button type="danger" v-on:click="dialogFormVisible = false;removeCalendar(clickInfo)" v-show="!isDialogVisible">删 除</el-button>
        </div>
      </el-dialog>
    <!--end:对话框--新建/修改日程-->

  </div> 
</template>

<script>
import FullCalendar, { renderMicroColGroup } from '@fullcalendar/vue'
import dayGridPlugin from '@fullcalendar/daygrid'
import timeGridPlugin from '@fullcalendar/timegrid'
import interactionPlugin from '@fullcalendar/interaction'
import { INITIAL_EVENTS, createEventId,formatDate,compare } from './event-utils'
import moment from "moment"
export default {
  components: {FullCalendar},
  data: function() {
    return {    
      calendarOptions: {
        firstDay:"1",
        weekNumberCalculation:"ISO" ,
        locale:"zh-cn",
        plugins: [
          dayGridPlugin,
          timeGridPlugin,
          interactionPlugin //交互插件
        ],
        headerToolbar: {
          left: 'prevYear,prev,next,nextYear today',
          center: 'title',
          right: 'dayGridMonth,timeGridWeek,timeGridDay'
        },
        initialView: 'dayGridMonth',//初始-月
        initialEvents:INITIAL_EVENTS, // 初始事件-测试数据
        editable: true,//允许事件被编辑
        selectable: true,
        selectMirror: true,
        dayMaxEvents: true,
        weekends: true,
        select: this.handleDateSelect,//选中
        eventClick: this.handleEventClick,//点击事件-触发
        eventsSet: this.handleEvents,
        buttonText:{today:"今天",month:"月",week:"周",day:"天"}
        },
      eventList: [],
      currentEvents: [],//当前事件
      dialogFormVisible:false,//对话框切换
      //事件
      form: {title:'',start:"",end:"",color: '#71b8ff',areaText:""},
      isAllday:true,//是否全天切换
      selectInfo:"",//存储已选择的日历视图
      clickInfo:"",//存储已选择的事件
      predefineColors: [
          '#9a80b9',
          '#ef4836',
          '#e99844',
          '#26a65b',
          '#d2527f',
          '#71b8ff',
        ],
      activeName:"1",
      dialog_title:"",//对话框title
      isDialogVisible:true, 
    }
  },
  methods: {
    //初始化eventList
    getEventList(){
      this.currentEvents.forEach(item=>{
        const tmp={
          id:item.id,
          title:item.title,
          allDay:item.allDay,
          start:item.start,
          startStr:item.allDay==true?item.startStr:formatDate(item.start),
          endStr:item.allDay==true?moment(item.end).subtract(1,'days').format('YYYY-MM-DD'):formatDate(item.end),
          dayStr:item.start.getFullYear()+'/'+item.start.getMonth()+'/'+item.start.getDate(),
          color:item.backgroundColor,
          areaText:"Lorem ipsum dolor, sit amet consectetur adipisicing elit. Quas fugiat magnam repellendus nihil minima. Omnis nihil consectetur sapiente modi doloremque. A consequatur inventore molestias et veritatis error tempore, laudantium magnam."
        }
        this.eventList.push(tmp) 
      })
    this.eventList.sort(compare("start"))
    },
    //重置表单
    resetForm(){
      this.form={title:'',start:"",end:"",color: '#71b8ff',areaText:""}
    },
    //新建日历事件
    handleDateSelect(selectInfo) {
      //当新建日程的时候，先重置表单
      this.resetForm()
      // 点击事件，打开对话框*********************************************************************
      this.dialogFormVisible=true
      this.selectInfo=selectInfo
      this.dialog_title="新建日程"
      this.isDialogVisible=true
      // 绑定日期数据****************************************************
      this.form.start=selectInfo.start
      this.form.end=selectInfo.allDay==true?moment(selectInfo.end).subtract(1, 'days'):selectInfo.end
      this.isAllday=selectInfo.allDay
      
    },
    //对话框确认--存储事件
    addCalendar(selectInfo){   
      let endAdj=moment(this.form.end).add(1, 'days')._d
      let calendarApi = selectInfo.view.calendar
      let id=createEventId()
      calendarApi.unselect()
      calendarApi.addEvent({
          id: id,
          title:this.form.title,
          start: this.form.start,
          end: endAdj,
          allDay: selectInfo.allDay,
          color:this.form.color,
          textColor:"#fff",
        })
    this.eventList.push({
      id: id,
      title:this.form.title,
      allDay: selectInfo.allDay,
      start: this.form.start,
      startStr: selectInfo.allDay==true?moment(this.form.start).format('YYYY-MM-DD'):formatDate(this.form.start),
      endStr:selectInfo.allDay==true?moment(this.form.end).format('YYYY-MM-DD'):formatDate(this.form.end),
      dayStr:this.form.start.getFullYear()+'/'+this.form.start.getMonth()+'/'+this.form.start.getDate(),
      color:this.form.color,
      areaText:this.form.areaText
      })
      //对新建的日程排序
      this.eventList.sort(compare("start"))
      
    },
    //************************************************************************************* 
    
    
    //修改日程************************************************************************************* 
    handleEventClick(clickInfo) {
      this.clickInfo=clickInfo
      this.dialogFormVisible=true
      this.dialog_title="修改日程"
      this.isDialogVisible=false
      this.form.title=clickInfo.event.title
      this.form.color=clickInfo.event.backgroundColor
      this.form.start=clickInfo.event.start
      this.form.end=moment(clickInfo.event.end).subtract(1,"days")
      this.form.areaText=this.eventList.find(item => item.id === clickInfo.event.id).areaText
      // console.log(this.eventList);
    },
    //对话框确认--存储事件
    updateCalendar(clickInfo){  
      clickInfo.event.remove()
      let endAdj=moment(this.form.end).add(1, 'days')._d
      let tmp_api=clickInfo
      let calendarApi = tmp_api.view.calendar
      let id=createEventId()
      calendarApi.unselect()
      calendarApi.addEvent({
          id: id,
          title:this.form.title,
          start: this.form.start,
          end: endAdj,
          allDay: clickInfo.event.allDay,
          color:this.form.color,
          textColor:"#fff",
        })
      this.eventList.splice(this.eventList.findIndex(item => item.id === clickInfo.event.id),1);
      this.eventList.push({
        id: id,
        title:this.form.title,
        allDay: clickInfo.event.allDay,
        start: this.form.start,
        startStr: clickInfo.event.allDay==true?moment(this.form.start).format('YYYY-MM-DD'):formatDate(this.form.start),
        endStr:clickInfo.event.allDay==true?moment(this.form.end).format('YYYY-MM-DD'):formatDate(this.form.end),
        dayStr:this.form.start.getFullYear()+'/'+this.form.start.getMonth()+'/'+this.form.start.getDate(),
        color:this.form.color,
        areaText:this.form.areaText
        })
      //对修改后的日程排序
      this.eventList.sort(compare("start"))
    },
    removeCalendar(clickInfo){
     this.$confirm(`你确定要删除'${clickInfo.event.title}'事件吗？`, '提示', {
          confirmButtonText: '确定',
          cancelButtonText: '取消',
          type: 'warning'
        })
        .then(()=>{
          clickInfo.event.remove()
          this.eventList.splice(this.eventList.findIndex(item => item.id === clickInfo.event.id),1);
          this.eventList.sort(compare("start"))
          })
        .catch(()=>{"取消了删除操作"})
    },
    //添加事件
    handleEvents(events) {
      this.currentEvents = events
    },
    deleteCalendar(id){
      let tmp=this.currentEvents.find(item => item.id === id)
       this.$confirm(`你确定要删除'${tmp.title}'事件吗？`, '提示', {
          confirmButtonText: '确定',
          cancelButtonText: '取消',
          type: 'warning'
        })
        .then(()=>{
          tmp.remove()
          this.eventList.splice(this.eventList.findIndex(item => item.id === id),1);
          this.eventList.sort(compare("start"))
          })
        .catch(()=>{"取消了删除操作"})   
    }
  },
  mounted(){
    this.getEventList()
  },
}
</script>

<style lang='less' scoped>
.demo-app {
  // box-sizing: border-box;
  display: flex;
  min-height: 100%;
  background-color: #fff;
}

b { 
margin-right: 3px;
font-size: 12px;
}

i{
  font-style: normal;
  font-size: 12px;
}

.demo-app-main {
  width: 98%;
  display: flex;
  flex-direction: row;
  justify-content: center;
  align-items: flex-start;
  padding: 10px 10px 0 10px;
  margin: 0 auto;
  /*日程列表样式*/
  .el-collapse{
    flex: 2;
    max-width:350px;
    padding: 10px 10px 0 5px;
    margin: 20px auto;
    border: none;
    >.tips{
    // background-color: var(--themeColor--);
    background-image: linear-gradient(45deg,rgba( #92D050 ,0.75)0%,rgba( #1480D1 ,0.75)  64%, rgba( #2958BE ,0.75) 69%, rgba( #002060 ,0.75) 100%);
    color:#fff;
    }
    .totalSchedule{
        color: #8b91a0;
        font-size: 20px;
        font-weight: 300;
        display: flex;
        >span{
          width:20px;height: 25px;
          text-align: center;
          display: block;
          font-family:'Times New Roman', Times, serif;
          font-size: 20px;
          font-weight: bolder;
          padding: 0 5px;
          margin: 0 5px;
          background-color: #ec4638;
          color: #fff;
        }
      }
    
  }
  /*日历样式*/
  .fc { 
    flex: 8;
    max-width: 1250px;
    margin: 0 auto;
    background-color: #fff;
    padding: 20px 5px 0 0;
    font-family: "Source Sans Pro", "Helvetica Neue", Arial, Helvetica, sans-serif;
  }
}




.demo-app /deep/.el-collapse-item__wrap{
  width: 100%;height: 100%;
  background-color: #f3f3f4;
  display: flex;
  justify-content: center;
  align-items: center;
  padding: 10px 0;
  border-top: 2px solid #676a6c;
  //  width: 230px;height: 230px;
  // background-color: #ffc;
}
.demo-app /deep/.el-collapse-item__content{
  width: 250px;height: 250px;
  background-color: #ffc;
  color: #000;
  border-radius: 4px;
  box-shadow: 5px 5px 7px rgba(33, 33, 33, 0.7);
  padding: 15px;
  -webkit-transition: -webkit-transform 0.15s linear;
  -webkit-transform:rotate(-6deg) scale(0.9,0.9) ;
  font-size: 15px;
  font-family: '微软雅黑';
  position: relative;
  .el-popover__reference{
    height: 130px;
    overflow: hidden;
    text-overflow: ellipsis;
  }
  
  .list_Title{
    font-size: 15px;
    font-weight: 700;
  }
  .start_end{
     font-size: 13px;
     padding-bottom: 10px;
  }
  .deleteCalendar{
    position: absolute;
    right: 5px;
    bottom: 5px;
    background-color:transparent;
    border: none;
    .el-icon-delete{
      font-size: 14px;
    }
  }
.deleteCalendar:hover{
      cursor: pointer;
      background-color:transparent;
      border: none;
      color:red;
} 
 
}
.demo-app /deep/.el-collapse-item__content:hover{
  -webkit-transform:rotate(0deg);
}

// .el-collapse-item__content > div{
//   padding: 5px 0;
//   // border-bottom: 1px solid;
//   // border-image: -webkit-linear-gradient(90deg, rgba(255,255,255,0.00) 0%, #DCDCDC 50%, rgba(255,255,255,0.00) 99%) 2 2 2 2;
//   // border-image: -moz-linear-gradient(90deg, rgba(255,255,255,0.00) 0%, #DCDCDC 50%, rgba(255,255,255,0.00) 99%) 2 2 2 2;
//   // border-image: linear-gradient(90deg, rgba(255,255,255,0.00) 0%, #DCDCDC 50%, rgba(255,255,255,0.00) 99%) 2 2 2 2;
// }
.demo-app /deep/.el-collapse-item__header{
      height: 31px;
      color: #8b91a0;
      // background-color: #71b8ff;color: #FAFAFA;
      // border: 0.1px solid #71b8ff;
      font-size:14px;
      font-family: Arial, Helvetica, sans-serif;
      border-radius: 4px;
      padding: 0px 10px;
      margin: 5px 0;
      white-space: nowrap;
      overflow: hidden;
      text-overflow: ellipsis;
      > i{
        font-size: 15px;
        padding: 0 10px 0 5px;
      }
    }
.demo-app /deep/.el-collapse-item__header:hover{
      color: #3699ff;
      font-weight: 400;
    }
.demo-app /deep/.el-collapse-item__header.is-active{
    // background-color: #fff;
    // border-radius: 5px;
    // color: #8b91a0;
    color: #3699ff;
    font-weight: 400;
    }






.demo-app /deep/.fc-toolbar-title{
  font-weight: 400;
  font-size: 25px;
  padding: 0;margin: 0;
}

.demo-app /deep/.fc-button{
  width: 75px;height: 34px;
   background-color: #fff;
   color: #58666e;
   border: 0.01px solid #ddd;
   font-size: 14px;  
   font-weight: 400;
   box-shadow: none;
   text-align: center;
 }
.demo-app /deep/.fc-icon {
font-size: 18px;

   }
.demo-app /deep/.fc-button-primary:hover{
  background-color: #fafafa;
  // border: 0.1px solid var(--themeColor--);
  box-shadow: none;
}

.demo-app /deep/.fc-button-primary.fc-button-active:focus{
  box-shadow: none;
  background-color: #f3f4f5;
  border: 0.01px solid #ddd;
  color: #399BFF
}
.demo-app /deep/.fc .fc-button-primary:not(:disabled).fc-button-active{
  box-shadow: none;
  background-color: #f3f4f5;
  border: 0.01px solid #ddd;
  color: #399BFF
}
.demo-app /deep/.fc .fc-button-primary:not(:disabled):active{
  box-shadow: none;
  background-color: #f3f4f5;
  border: 0.01px solid #ddd;
  color: #399BFF
}

.demo-app /deep/.fc-col-header-cell{
  font-size: 14px;
  font-weight: 400;
  color: black;
}
.demo-app /deep/.fc-daygrid-day-top{
  font-size: 14px;
  font-weight: 400;
  color: #222;
  text-emphasis: center;

}

.demo-app /deep/.fc-daygrid-event{
    overflow: hidden;
  }

.demo-app /deep/.fc-daygrid-event-harness{
  margin: 5px;
}
.demo-app /deep/.fc-event{
  background-color: #71b8ff;
  border: none;
}
.demo-app /deep/.fc-event-main{
  height: 21px;
  padding: 3px 0;
}




/*对话框样式 */
.demo-app /deep/.el-dialog{
    width:380px;
    min-height:450px;
    padding: 0;
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: center;
    border-radius: 10px;
    position: relative;
    .el-dialog__header{
      flex: 1.5;
    width: 90%;
    // position: absolute;
    // top:10px;
    
    padding: 15px 15px 10px 15px;
      .el-dialog__title{
      font-size: 20px;
      font-weight:300;
      // color: #C0C0C0;
      }
    }
    .el-dialog__body{
      flex: 8;
    width: 90%;
    padding: 0 15px 0 15px;
    display: flex;
    flex-direction: column;  
    }
    .el-form-item{
    margin: 5px 0;
    }
    .el-dialog__footer{
    position: absolute;
    bottom: 10px;right: 10px;
    padding: 0 10px; 
    }
    .el-form-item__label{
    padding: 0 10px 0 0 ;
    margin: 0;
    font-size: 13px;
    }
    .el-input__inner{
      border: 0.5px solid #F5F5F5;
    }
    .el-input__inner:focus,.el-input__inner:active{
      border: 2px solid #1867c0;
      background-color: #f7fbfd;
    }
    .el-textarea__inner{
      border: none;
      line-height: 30px;
      padding: 5px 0;
      border-radius: 0;
      border-bottom: 0.5px solid #F5F5F5;
      font-family: "Source Sans Pro", "Helvetica Neue", Arial, Helvetica, sans-serif;
      
    }
    .el-textarea__inner:focus,.el-textarea__inner:active{
        animation: ad_width .5s linear forwards;
        border-bottom: 2px solid #1867c0;
        caret-color: #1867c0;
        background-color: #f7fbfd;
      }

    .title{
      width: 100%;
      border: none;
      > .el-input__inner{
      padding: 5px 0;
      border: none;
      border-radius: 0;
      border-bottom: 0.5px solid #F5F5F5;
      }
      >.el-input__inner:focus, >.el-input__inner:active{
      animation: ad_width .5s linear forwards;
      border-bottom: 2px solid #1867c0;
      caret-color: #1867c0;
      background-color: #f7fbfd;
      
      }
    }
    .el-dialog__footer{
      flex: 1;
      // position: absolute;
      // bottom: 20px;

    }
    .dialog-footer >.el-button{
      height: 35px;width: 70px;
      text-align: center;
      padding: 0 12px;
      margin: 0 12px 0 0 ;
      font-size: 15px;
      font-weight: 400;
      }
      .dialog-footer >.el-button:hover{
        background-color:#f5f5f5
      }
      .dialog-footer > .el-button--primary{
        background-color: #fff;
        border: none;
        color: #1867c0;
        }
      .dialog-footer > .el-button--danger{
        background-color: #fff;
        border: none;
        color: #ff5757;
      }
      .dialog-footer > .el-button--default{
        background-color: #fff;
        border: none;
        color:#A9A9A9;
        }
}


@keyframes ad_width {
    from {
        width: 0
    }
    to {
        width: 302px
    }
}
</style>
